﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using CrystalCore.Libs;
using CrystalCore.Mapping;

namespace CrystalCore.Structure
{
    [Serializable]
    public class LevelMap
    {
        //Fields
        [NonSerialized]
        public Game Game;

        private List<CellBase> GameCells;

        public int MapWidth { get; private set; }
        public int MapDepth { get; private set; }

        //cTor  
        public LevelMap(Game game, int Width, int Depth)
        {
            this.Game = game;
            this.GameCells = new List<CellBase>();
            this.MapWidth = Width;
            this.MapDepth = Depth;
            this.CreateBlankMap();
        }
        public LevelMap(Game game, int[,] Data)
        {
            this.Game = game;
            this.GameCells = new List<CellBase>();
            this.MapWidth = Data.GetLength(1);
            this.MapDepth = Data.GetLength(0);
            this.CreateMapFrom(Data);
        }

        //Methods
        private void CreateBlankMap()
        {
            for (int z = 0; z < MapDepth; z++)
                for (int x = 0; x < MapWidth; x++)
                    GameCells.Add(CellFactory.CreateInstance<EmptyCell>(new MazePosition(x, z)));

            RegisterAllCells();
        }
        private void CreateMapFrom(int[,] data)
        {
            for (int z = 0; z < MapDepth; z++)
            {
                for (int x = 0; x < MapWidth; x++)
                {
                    MazePosition position = new MazePosition(x, z);
                    switch ((CellConversionIndex)data[z, x])
                    {                       
                        case 0:
                        case CellConversionIndex.NONE:
                            break;

                        case CellConversionIndex.FLOOR_EARTH: 
                            GameCells.Add(CellFactory.CreateInstance<EarthFloorCell>(position)); break;
                        
                        case CellConversionIndex.FLOOR_FIRE: 
                            GameCells.Add(CellFactory.CreateInstance<FireFloorCell>(position)); break;
                        
                        case CellConversionIndex.FLOOR_WATER:
                            GameCells.Add(CellFactory.CreateInstance<WaterFloorCell>(position)); break;
                        
                        case CellConversionIndex.FLOOR_AIR: 
                            GameCells.Add(CellFactory.CreateInstance<AirFloorCell>(position)); break;

                        case CellConversionIndex.BRIDGE: break; // GameCells.Add(CellFactory.CreateInstance<GateCell>(Game, new MazePosition(x, z))); break;
                    }                    
                }
            }
            RegisterAllCells();
        }

        public CellBase GetCell(MazePosition position)
        {
            return (GameCells.Where(c => c.MazePosition == position).FirstOrDefault());
        }
        public CellBase GetCell(int X, int Z)
        {
            return (GameCells.Where(c => c.MazePosition == new MazePosition(X, Z)).FirstOrDefault());
        }

        public void RegisterAllCells()
        {
            SelectionEngine.Clear();
            SelectionEngine.RegisterRange(GameCells);
        }
        public void DrawMap()
        {
            foreach (CellBase cell in GameCells)
                cell.DrawCell();
        }

        public bool CanUserWalk(int x, int y)
        {
            CellBase cell = GameCells.Where(c => { return (c.MazePosition.X == x && c.MazePosition.Z == y); }).SingleOrDefault();

            if (cell == null)
                return false;

            else
            {
                if (cell is FloorCell)
                    return true;
                else
                    return false;
            }

        }

    }
}
